//
//  CYTool.m
//  CreditAddressBook
//
//  Created by Lee on 15/8/19.
//  Copyright (c) 2015年 Lee. All rights reserved.
//

#import "CYTool.h"
#import "LERange.h"
#import <objc/runtime.h>

static inline void swizzleSelector(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector) {
    Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector);
    method_exchangeImplementations(originalMethod, swizzledMethod);
}

static inline BOOL addMethod(Class class, SEL selector, Method method) {
    return class_addMethod(class, selector, method_getImplementation(method),  method_getTypeEncoding(method));
}

@implementation CYTool

/**
 *  cell从下到上显示动画效果
 *
 *  @param table
 */
+ (void)cellAnimationWithTableView:(UITableView *)tableView {
    //重载一下数据
    [tableView reloadData];
    //动画延时
    CGFloat diff = 0.05;
    //获取tableView的高
    CGFloat tableHeight = tableView.bounds.size.height;
    //获取所有的单元格
    NSArray *cells = [tableView visibleCells];
    //遍历单元格，将之隐藏
    for (UITableViewCell *cell in cells) {
        cell.transform = CGAffineTransformMakeTranslation(0, tableHeight);
    }
    
    //遍历cell，顺序执行上移的动画
    for (int i = 0; i < cells.count; i++) {
        UITableViewCell *cell = cells[i];
        //根据序列号决定延迟时间
        CGFloat delay = diff * i;
        //执行动画
        [UIView animateWithDuration:1 delay:delay options:UIViewAnimationOptionCurveEaseInOut animations:^{
            //重新回到原始位置
            cell.transform = CGAffineTransformMakeTranslation(0, 0);
        } completion:nil];
    }
}

+ (int)characterToASCII:(unichar)cha {
    int a = cha;
    return a;
}

+ (NSString *)stringToASCII:(NSString *)str {
    NSString *astr = @"";
    for (int i = 0; i < str.length; i++) {
        astr = [astr stringByAppendingFormat:@"%d", [self characterToASCII:[str characterAtIndex:i]]];
    }
    return astr;
}

+ (void)setExtraCellLineHiddenWithTableView:(UITableView *)tableView {
    UIView *view =[[UIView alloc]init];
    view.backgroundColor = [UIColor clearColor];
    [tableView setTableFooterView:view];
//    [tableView reloadData];
}

//url地址字典提取
+ (NSDictionary*)getURLParameter:(NSString*)urlString{
     if (urlString.length == 0) {
          return  nil;
     }
     NSMutableDictionary *dict =[NSMutableDictionary dictionary];
     NSArray *urlArray = [urlString componentsSeparatedByString:@"?"];
     
     
     if (urlArray.count > 1) {   //如果大于1，认为有参数
          NSString *URLParString = [urlArray lastObject];
          
          if ([URLParString rangeOfString:@"&"].location != NSNotFound) { //多个参数
               NSArray *dictArray = [URLParString componentsSeparatedByString:@"&"];
               for (NSString *KVString in dictArray) {
                    NSArray *KVArray = [KVString componentsSeparatedByString:@"="];
                    for (int i = 0; i < KVArray.count; i++) {
                         if (i == KVArray.count - 1) {
                              [dict setValue:KVArray[i] forKey:KVArray[i - 1]];
                         }
                    }
               }
          }else if ([URLParString rangeOfString:@"="].location != NSNotFound){ //单个参数
               NSArray *dictArray = [URLParString componentsSeparatedByString:@"="];
               for (int i = 0; i < dictArray.count; i++) {
                    if (i == dictArray.count - 1) {
                         [dict setValue:dictArray[i] forKey:dictArray[i - 1]];
                    }
               }
          }
     }
     
     return dict;
}



/**
 *  判断手机号是否合法
 *
 *  @param string
 *
 *  @return
 */
+ (BOOL) isphoneNumber:(NSString *)number{
     NSString *phoneRegex1=@"1[34578]([0-9]){9}";
     NSPredicate *phoneTest1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",phoneRegex1];
     return  [phoneTest1 evaluateWithObject:number];
     
}

/**
 *  判断身份证是否合法
 *
 *  @param string
 *
 *  @return
 */
+ (BOOL) isidcard:(NSString *)idcard{
     
     if (idcard.length <= 0) {
          return NO;
     }
     NSString *regex2 = @"^(\\d{14}|\\d{17})(\\d|[xX])$";
     NSPredicate *identityCardPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex2];
     return [identityCardPredicate evaluateWithObject:idcard];
}

/**
 *  判断邮箱是否合法
 *
 *  @param string
 *
 *  @return
 */
+ (BOOL) IsEmailAdress:(NSString *)Email
{
     NSString *emailCheck = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
     NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES%@",emailCheck];
     return [emailTest evaluateWithObject:Email];
}

/**
 *  判断银行卡是否合法
 *
 *  @param string
 *
 *  @return
 */
+ (BOOL) IsBankCard:(NSString *)cardNumber
{
     if(cardNumber.length==0)
     {
          return NO;
     }
     NSString *digitsOnly = @"";
     char c;
     for (int i = 0; i < cardNumber.length; i++)
     {
          c = [cardNumber characterAtIndex:i];
          if (isdigit(c))
          {
               digitsOnly =[digitsOnly stringByAppendingFormat:@"%c",c];
          }
     }
     int sum = 0;
     int digit = 0;
     int addend = 0;
     BOOL timesTwo = false;
     for (NSInteger i = digitsOnly.length - 1; i >= 0; i--)
     {
          digit = [digitsOnly characterAtIndex:i] - '0';
          if (timesTwo)
          {
               addend = digit * 2;
               if (addend > 9) {
                    addend -= 9;
               }
          }
          else {
               addend = digit;
          }
          sum += addend;
          timesTwo = !timesTwo;
     }
     int modulus = sum % 10;
     return modulus == 0;
}


/**
 *  判断字符串中是否包含表情符号
 *
 *  @param string
 *
 *  @return
 */
+ (BOOL)stringContainsEmoji:(NSString *)string {
    __block BOOL returnValue = NO;
    
    [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
     ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
         
         const unichar hs = [substring characterAtIndex:0];
         
         if (0xd800 <= hs && hs <= 0xdbff) {
             if (substring.length > 1) {
                 const unichar ls = [substring characterAtIndex:1];
                 const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                 if (0x1d000 <= uc && uc <= 0x1f77f) {
                     returnValue = YES;
                     *stop = YES;
                 }
             }
         } else if (substring.length > 1) {
             const unichar ls = [substring characterAtIndex:1];
             if (ls == 0x20e3) {
                 returnValue = YES;
                 *stop = YES;
             }
             
         } else {
             if (0x2100 <= hs && hs <= 0x27ff) {
                 returnValue = YES;
                 *stop = YES;
             } else if (0x2B05 <= hs && hs <= 0x2b07) {
                 returnValue = YES;
                 *stop = YES;
             } else if (0x2934 <= hs && hs <= 0x2935) {
                 returnValue = YES;
                 *stop = YES;
             } else if (0x3297 <= hs && hs <= 0x3299) {
                 returnValue = YES;
                 *stop = YES;
             } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                 returnValue = YES;
                 *stop = YES;
             }
         }
     }];
    return returnValue;
}

/**
 *  返回字符串中包含的表情符号集
 *
 *  @param string
 *
 *  @return
 */
+ (NSArray *)stringContainsEmojis:(NSString *)string {
    NSMutableArray *ranges = [NSMutableArray array];
    [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
     ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
         
         const unichar hs = [substring characterAtIndex:0];
         
         if (0xd800 <= hs && hs <= 0xdbff) {
             if (substring.length > 1) {
                 const unichar ls = [substring characterAtIndex:1];
                 const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                 if (0x1d000 <= uc && uc <= 0x1f77f) {
                     [ranges addObject:[[LERange alloc] initWithSubStr:substring range:substringRange]];
                 }
             }
         } else if (substring.length > 1) {
             const unichar ls = [substring characterAtIndex:1];
             if (ls == 0x20e3) {
                 [ranges addObject:[[LERange alloc] initWithSubStr:substring range:substringRange]];
             }
             
         } else {
             if (0x2100 <= hs && hs <= 0x27ff) {
                 [ranges addObject:[[LERange alloc] initWithSubStr:substring range:substringRange]];
             } else if (0x2B05 <= hs && hs <= 0x2b07) {
                 [ranges addObject:[[LERange alloc] initWithSubStr:substring range:substringRange]];
             } else if (0x2934 <= hs && hs <= 0x2935) {
                 [ranges addObject:[[LERange alloc] initWithSubStr:substring range:substringRange]];
             } else if (0x3297 <= hs && hs <= 0x3299) {
                 [ranges addObject:[[LERange alloc] initWithSubStr:substring range:substringRange]];
             } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                 [ranges addObject:[[LERange alloc] initWithSubStr:substring range:substringRange]];
             }
         }
     }];
    return ranges;
}

/**
 *  返回字符串中中文字符，数字，字母集合
 *
 *  @param string
 *
 *  @return
 */
+ (NSString *)stringForZh:(NSString *)string {
    __block NSString *ranges = @"";
    [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
     ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
         
         const unichar hs = [substring characterAtIndex:0];
         
         if (0x4E00 <= hs && hs <= 0x9FA5) {//常用汉字
             ranges = [ranges appendingString:substring];
         } else if (0x0020 <= hs && hs <= 0x007E) {//数字，字母，常用符号
             ranges = [ranges appendingString:substring];
         } else if (hs == 0x00A0) {
//             ranges = [ranges appendingString:substring];
         }
     }];
    return ranges;
}

/**
 *  祛除姓名中的表情图片
 */
+ (NSString *)formatName:(NSString *)name {
    BOOL result = [CYTool stringContainsEmoji:name];
    if (result) {
        NSArray *ranges = [CYTool stringContainsEmojis:name];
        //        CYLog(@"=======");
        for (LERange *range in ranges) {
            //            CYLog(@"name: %@ -- %lu", range.subStr, (unsigned long)range.subStrRange.location);
            name = [name replaceAll:range.subStr with:@""];
        }
        //        CYLog(@"NewName: %@", name);
        //        CYLog(@"=======");
    }
    return name;
}

/**
 *  只取出字符串中的中文，数字，字母
 */
+ (NSString *)formatNameToZh:(NSString *)name {
    NSString *ranges = [CYTool stringForZh:name];
    if (ranges.length > 30) {
//        CYLog(@"%@长度过长：%lu", ranges, (unsigned long)ranges.length);
        [self reportReason:CYStringFormat(@"%@长度过长：%lu", ranges, (unsigned long)ranges.length)];
        ranges = [ranges substringToIndex:20];
    }
    //    CYLog(@"=======");
    //    CYLog(@"oldName: %@", name);
    //    CYLog(@"NewName: %@", ranges);
    //    CYLog(@"=======");
    return ranges;
}

+ (NSDictionary *)plistData:(NSData *)data {
    NSError *error = nil;
    if (data && data.length) {
        NSPropertyListFormat format;
        NSDictionary *plist = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:&format error:&error];
        if (!error) {
            return plist;
        }
    }
    CYLog(@"plist转字典错误: %@", error);
    return nil;
}
/**
 *  将originalClass中的originalSEL更换为swizzledClass的swizzledSEL调用
 *
 *  @param originalClass
 *  @param originalSEL
 *  @param swizzledClass
 *  @param swizzledSEL
 */
+ (void)swizzleWhthOriginalClass:(Class)originalClass originalSEL:(SEL)originalSEL swizzledClass:(Class)swizzledClass swizzledSEL:(SEL)swizzledSEL {
    swizzleSelector(originalClass, originalSEL, swizzledClass, swizzledSEL);
    
    // 获取到UIWindow中sendEvent对应的method
    //    Method sendEvent = class_getInstanceMethod([UIWindow class], @selector(sendEvent:));
    //    Method sendEventMySelf = class_getInstanceMethod([self class], @selector(sendEventHooked:));
    
    // 将目标函数的原实现绑定到sendEventOriginalImplemention方法上
    //    IMP sendEventImp = method_getImplementation(sendEvent);
    //    class_addMethod([UIWindow class], @selector(sendEventOriginal:), sendEventImp, method_getTypeEncoding(sendEvent));
    
    // 然后用我们自己的函数的实现，替换目标函数对应的实现
    //    IMP sendEventMySelfImp = method_getImplementation(sendEventMySelf);
    //    class_replaceMethod([UIWindow class], @selector(sendEvent:), sendEventMySelfImp, method_getTypeEncoding(sendEvent));
}
/**
 *  给class添加一个方法：selector
 *
 *  @param class          添加方法的类
 *  @param selector       添加的方法的方法名
 *  @param targetClass    方法的实现类
 *  @param targetSelector 实现方法的函数
 */
+ (void)addMethodWhthClass:(Class)class selector:(SEL)selector targetClass:(Class)targetClass targetSelector:(SEL)targetSelector {
    Method afSuspendMethod = class_getInstanceMethod(targetClass, targetSelector);
    addMethod(class, selector, afSuspendMethod);
}
@end
